﻿using System;
using System.Collections.Generic;
using System.Web;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Criterion;
using System.Reflection;
using System.Web.Hosting;
using System.IO;
using NHibernate.Mapping.Attributes;
using VemTransporte.Models.Basica;

namespace VemTransporte.Models.Persistencia
{
    public abstract class GenericNHibernateDAO<T, IdDataType> : IGenericDAO<T, IdDataType> where T : class
    {
        private Type persitentType = typeof(T);

        public static ISession Session
        {
            get
            {
                return NHibernateHelper.Session;
            }
        }

        protected IList<T> GetByCriteria(params ICriterion[] criterion)
        {

            ICriteria criteria = Session.CreateCriteria(typeof(T));

            foreach (ICriterion criterium in criterion)
            {
                criteria.Add(criterium);
            }

            return criteria.List<T>();
        }

        public void CloseSession()
        {
            NHibernateHelper.CloseSession();
        }

        public T Salvar(T entity)
        {
            ITransaction transaction = null;
            try
            {

                transaction = Session.BeginTransaction();

                Session.Save(entity);

                Session.Flush();

                transaction.Commit();

                return entity;
            }
            catch (Exception ex)
            {
                if (transaction != null)
                {
                    transaction.Rollback();
                }
                throw new Exception(ex.Message);
            }

        }

        public T Alterar(T entity)
        {
            ITransaction transaction = null;
            try
            {
                transaction = Session.BeginTransaction();

                Session.Update(entity);

                Session.Flush();

                transaction.Commit();

                return entity;
            }
            catch (Exception ex)
            {
                if (transaction != null)
                {
                    transaction.Rollback();
                }
                throw new Exception(ex.Message);
            }
        }

        public void Excluir(T entity)
        {
            ITransaction transaction = null;
            try
            {
                transaction = Session.BeginTransaction();

                Session.Delete(entity);

                Session.Flush();

                transaction.Commit();

            }
            catch (Exception ex)
            {
                if (transaction != null)
                {
                    transaction.Rollback();
                }

                throw new Exception(ex.Message);
            }
        }

        public T ProcurarPorId(IdDataType id)
        {
            try
            {
                return (T)Session.Load(typeof(T), id);
                //return Session.Get<T>(id).;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public IList<T> ProcurarTodos()
        {
            IList<T> lista;

            try
            {
                
                IQuery query = Session.CreateQuery("from " + typeof(T).Name);
                lista = query.List<T>();
            
                //lista = Session.CreateCriteria(typeof(T)).List<T>();

                return lista;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
    }

}